package productions;

import exceptions.ParserException;
import lexico.ErrorTable;
import lexico.SymbolTable;
import lexico.TokenClass;

/**
 * @author maocleal
 */
public class SentencaProduction extends AbstractProductionRule {
    /* Muitos dos métodos irão precisar de algo assim: */

    private static SentencaProduction instance = new SentencaProduction();

    public static SentencaProduction getInstance() {
        return instance;
    }

    /**
     * Regra: sentenca : IDENTIFIER chamada_funcao|((array)* ('=' valor | op_inc*));
     * @return
     * @throws ParserException
     */
    @Override
    public boolean analyze(SymbolTable st, ErrorTable et) throws ParserException {
        if (!basicParse(st, TokenClass.IDENTIFIER)) {
            return false;
        }

        if (ChamadaFuncaoProduction.getInstance().analyze(st, et)) {
            return true;
        }

        while (ArrayProduction.getInstance().analyze(st, et)) {
        }

        if (basicParse(st, TokenClass.OPERATOR_ASSIGNMENT)) {
            if (!ValorProduction.getInstance().analyze(st, et)) {
                return skipUntilSynchronize(st, et, "Era esperado uma atribuição");
            }
            return true;
        }



        while (OpIncProduction.getInstance().analyze(st, et)) {
        }

        return true;
    }

    @Override
    protected void populateFirst() {
        first.add(TokenClass.IDENTIFIER);
    }

    @Override
    protected void populateFollow() {
        follow.add(TokenClass.DELIMITER_SEMICOLON);
    }
}
